/**
 * 柱线组合图
 */
import React from 'react';
import { DualAxes, DualAxesOptions } from '@antv/g2plot';
// import { message } from 'antd';
import { DL_TYPE, WD_TYPE, THEME_COLOR } from 'src/pages/AnalyseManage/EditReport/components/EditorDataType/EnumConfig';
import { getComponentData } from 'src/services/AnalyseManage';
// import { transformDataUnitData } from 'src/libs/utils';

import { ChartService, IProps } from 'src/pages/AnalyseManage/EditReport/components/ChartsType/components/ChartService';
import { CHART_LINK } from 'src/pages/AnalyseManage/EditReport/topics';
import PubSub from 'pubsub-js';
import { digitFormat, isNumber } from 'src/libs/utils';

const DEFAULT_DATA = {
	rows: [
		{ name: '2019-03', value: 350, category: '电器' },
		{ name: '2019-04', value: 900, category: '电器' },
		{ name: '2019-05', value: 300, category: '电器' },
		{ name: '2019-06', value: 450, category: '电器' },
		{ name: '2019-07', value: 470, category: '电器' },
	],
	y2: [
		{ name: '2019-03', value2: 350, category: '电脑' },
		{ name: '2019-04', value2: 900, category: '电脑' },
		{ name: '2019-05', value2: 300, category: '电脑' },
		{ name: '2019-06', value2: 450, category: '电脑' },
		{ name: '2019-07', value2: 470, category: '电脑' },
	]
};

export default class ColumnLineChart extends ChartService {

	state = {
		chartEl: null,
		rows: [],
		y2: [],
		xField: 'name',
		yField: 'value',
		yField2: 'value2',
		seriesField: 'category',
		xAlias: 'name',
		yLAlias: 'value',
		yRAlias: 'value2',
		eventToken: [],
		dependencies: [],	//	图表联动参数
		isRender: false
	};

	// 设置标签样式
	getPointOptions = ( style, dataConfig ) => {
		let config = {
			size: style.chartLabelMarkSize || 5,
			// size: 0,
			shape: style.chartLabelMarkType ? ( style.chartLabelMarkType === 'hollowCircle' ? 'hollow-circle' : style.chartLabelMarkType ) : 'circle',
			style: {
				fill: '',
				stroke: '',
				lineWidth: 2,
				fillOpacity: dataConfig.lineType === 'basic' ? 0 : 1
			},
			color: style.chartLabelMarkColor || 'rgb(134, 188, 37)',
		};
		// 如果是空心圆需要填充白色
		if ( style.chartLabelMarkType === 'hollowCircle' ) {
			config.style.fill = 'white';
			// config.style.stroke = '#5B8FF9'; // inherit
			config.style.lineWidth = 2;
		}

		//	只有设置了数据点，才可以点击联动，所以在basic下，设置数据点为透明
		return style.isShowMarker ? config : null;
	};

	getConfig = (): DualAxesOptions => {
		const { config = {} } = this.props;
		const { style = {}, data = {} } = config;
		const customBlockColor = style.customBlockColor || [];
		const { yLAxis = [] } = data;
		const yLAxisColor = customBlockColor.slice( 0, yLAxis.length );
		const yRAxisColor = customBlockColor.slice( yLAxis.length );
		// console.log( yLAxisColor, yRAxisColor, style.customBlockColor );
		return {
			autoFit: true,
			data: [ this.state.rows, this.state.y2 ],
			xField: this.state.xField,
			yField: [ this.state.yField, this.state.yField2 ],
			theme: { maxColumnWidth: style.columnWidth },
			geometryOptions: [
				{
					color: ( yLAxisColor.map( ( v ) => v.color ) ).concat( THEME_COLOR ),
					seriesField: this.state.seriesField,
					geometry: 'column',
					isGroup: true,
					marginRatio: style.columnMargin,
					columnStyle: {
						style: {
							borderRadius: style.columnRadio,
						}
					},
					label: style.isShowLabelData && style.showArea?.indexOf( 'column' ) !== -1 ?
						{
							position: style.chartLabelPosition || 'top', // 'top', 'bottom', 'middle',
							style: {
								fontFamily: style.labelFontFamily,
								fontSize: parseInt( style.labelFontSize || 15 ),
								fontWeight: style.labelFontBold ? 'bold' : 'normal',
								fontStyle: style.labelFontItalic ? 'italic' : 'normal',
								fill: style.labelFontColor || '#333',
							},
							formatter: ( data ) => {
								let { value, precision = '', dataUnit = '' } = data;
								const valueList = this.state.rows.map( t => t.value );
								const maxValue = valueList.reduce( ( acc, cur ) => acc > cur ? acc : cur );
								const minValue = valueList.reduce( ( acc, cur ) => acc > cur ? cur : acc );
								if (
									( style.onlyShowLabelMax && data.value === maxValue ) ||
									( style.onlyShowLabelMin && data.value === minValue ) ||
									( !style.onlyShowLabelMax && !style.onlyShowLabelMin )
								) {
									value = isNumber( precision ) ? value.toFixed( precision ) : value;
									return `${value}${dataUnit}`;
								}
							}
						} : null,
				},
				{
					color: ( yRAxisColor.map( ( v ) => v.color ) ).concat( THEME_COLOR ).reverse(),
					seriesField: this.state.seriesField || null,
					geometry: 'line',
					lineStyle: {
						lineWidth: style.chartLineWidth || 2,
					},
					point: this.getPointOptions( style, data ),
					label: style.isShowLabelData && style.showArea?.indexOf( 'line' ) !== -1?
						{
							position: style.chartLabelPosition || 'top', // 'top', 'bottom', 'middle',
							style: {
								fontFamily: style.labelFontFamily,
								fontSize: parseInt( style.labelFontSize || 15 ),
								fontWeight: style.labelFontBold ? 'bold' : 'normal',
								fontStyle: style.labelFontItalic ? 'italic' : 'normal',
								fill: style.labelFontColor || '#333',
							},
							formatter: ( data ) => {
								let { value, precision = '', dataUnit = '' } = data;
								const valueList = this.state.y2.map( t => t.value );
								const maxValue = valueList.reduce( ( acc, cur ) => acc > cur ? acc : cur );
								const minValue = valueList.reduce( ( acc, cur ) => acc > cur ? cur : acc );
								if (
									( style.onlyShowLabelMax && data.value === maxValue ) ||
									( style.onlyShowLabelMin && data.value === minValue ) ||
									( !style.onlyShowLabelMax && !style.onlyShowLabelMin )
								) {
									value = isNumber( precision ) ? value.toFixed( precision ) : value;
									return `${value}${dataUnit}`;
								}
							}
						} : null,
				},
			],
			appendPadding: [
				style.chartTopPadding || 150,
				style.chartRightPadding || 0,
				style.chartBottomPadding || 0,
				style.chartLeftPadding || 0
			],
			padding: 'auto',
			legend: style.isShowLegend === true ?
				{
					position: style.legendPosition,
					itemName: {
						style: {
							fill: style.legendFontColor,
							fontSize: parseInt( style.legendFontSize || 15 ),
							fontFamily: style.legendFontFamily,
							fontWeight: style.legendFontBold ? 'bold' : 'normal',
							fontStyle: style.legendFontItalic ? 'italic' : 'normal',
						},
					},
				} : false,
			tooltip: this.getToolTipConfig( style ),
			xAxis: {
				line: style.isShowDXLine ? {
					style: {
						stroke: style.chartLineColor,
					}
				} : null,
				title: style.isShowDXLine && style.isShowDXLineName ?
					{
						offset: 30,
						style: {
							// offset: 5,
							// textAlign: 'center',
							fontFamily: style.DXLineFontFamily,
							fontSize: parseInt( style.DXLineFontSize || 15 ),
							fontWeight: style.DXLineFontBold ? 'bold' : 'normal',
							fontStyle: style.DXLineFontItalic ? 'italic' : 'normal',
							fill: style.DXLineFontColor || '#333',
						},
					} : null,
				tickLine: style.isShowDXLine === false ? null : {},
				label: {
					style: style.chartLineDataColor
						? {
							fill: style.chartLineDataColor,
							fontSize: style.isShowDXLine === false ? 0 : 12,
						}
						: {
							// 设置X轴不显示，设置axis为null不生效，需要设置不显示label,line, tickline
							fontSize: style.isShowDXLine === false ? 0 : 12,
						},
					rotate: style.chartDXAxisLabelTilt ? style.chartDXAxisLabelTilt : 0,
				},
			},
			yAxis: [
				{
					line: style.isShowLYLine ?
						{
							style: {
								stroke: style.chartLineColor,
							},
						} : null,
					title: style.isShowLYLineName ?
						{
							style: {
								offset: 5,
								// textAlign: 'center',
								fontFamily: style.LYLineFontFamily,
								fontSize: parseInt( style.LYLineFontSize || 15 ),
								fontWeight: style.LYLineFontBold ? 'bold' : 'normal',
								fontStyle: style.LYLineFontItalic ? 'italic' : 'normal',
								fill: style.LYLineFontColor || '#333',
							},
						} : null,
					// 网格线样式
					grid: style.isHiddenLYGridLine
						? null
						: {
							line: {
								style: {
									stroke: style.chartGridlineColor,
								},
							},
						},
					// 设置坐标轴文字部分样式
					label: {
						formatter: ( v ) => {
							let value: any = parseFloat( v );
							if ( style.chartLYAxisDataUnit === 'percent' ) {
								value = `${value * 100}%`;
							}
							if ( style.chartLYAxisDataUnit === 'tenthousand' ) {
								value = `${value / 10000}万`;
							}
							if ( style.chartLYAxisDataUnit === 'million' ) {
								value =  `${value / 1000000}百万`;
							}
							return `${ value }${data.yLAxisUnit || ''}`;
						},
						style: style.chartLineDataColor
							? {
								fill: style.chartLineDataColor,
							}
							: {},
					},
				},
				data.columnType === 'doubleY' && {
					line: style.isShowRYLine
						? {
							style: {
								stroke: style.chartLineColor,
							},
						}
						: null,
					title: style.isShowRYLineName
						? {
							style: {
								// offset: 5,
								// textAlign: 'center',
								fontFamily: style.RYLineFontFamily,
								fontSize: parseInt( style.RYLineFontSize || 15 ),
								fontWeight: style.RYLineFontBold ? 'bold' : 'normal',
								fontStyle: style.RYLineFontItalic ? 'italic' : 'normal',
								fill: style.RYLineFontColor || '#333',
							},
						}
						: null,
					// 设置坐标轴文字部分样式
					label: {
						formatter: ( v ) => {
							let value: any = parseFloat( v );
							if ( style.chartRYAxisDataUnit === 'percent' ) {
								value = `${value * 100}%`;
							}
							if ( style.chartRYAxisDataUnit === 'tenthousand' ) {
								value = `${value / 10000}万`;
							}
							if ( style.chartRYAxisDataUnit === 'million' ) {
								value =  `${value / 1000000}百万`;
							}
							return `${ value }${data.yRAxisUnit || ''}`;
						},
						
						style: style.chartLineDataColor
							? {
								fill: style.chartLineDataColor,
							}
							: {},
					},
				} ],
			meta: {
				name: {
					alias: style.chartDXAxisName || 'name' ,
				},
				value: {
					alias: style.chartLYAxisName || 'value'
				},
				value2: {
					alias: style.chartRYAxisName || 'value2'
				},
			},
		};
	}

	// 设置tooltip
	getToolTipConfig = ( style ) => {
		return style.isShowToolTip
			? {
				// 设置toolTip相关样式
				domStyles: {
					'g2-tooltip-list-item': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor || '#333',
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
					'g2-tooltip-title': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor || '#333',
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
				},
				showCrosshairs: true,
				crosshairs: {
					line: {
						style: {
							stroke: style.chartHoverLineColor || 'rgba(33,33,33, 0.5)'
						}
					}
				},
				showMarkers: true,
				showContent: true,
				follow: true,
				fields: [ 'name', 'value', 'category', 'precision', 'dataUnit' ],
				formatter: ( datum ) => {
					let { category, value, precision = '', dataUnit = '' } = datum;
					value = isNumber( precision ) ? value.toFixed( precision ) : value;		//	小数尾数格式化
					value = digitFormat( value, 3 );				//	千分位格式化

					return {
						name: category,
						value: `${value}${dataUnit}`
					};
				},
			}
			: {
				showCrosshairs: false,
				showMarkers: false,
				showContent: false,
				domStyles: null,
				follow: false,
			};
	};

	itemInfo = ( v ) => {
		return {
			aggregateType: v.modelType === DL_TYPE ? v.aggregateType : '', //	度量的聚合类型
			formatType: v.modelType === WD_TYPE ? v.formatType : '', // 维度的聚合类型v.
			alias: v.title.trim(),
			dataType: v.dataType,
			frontendId: '',
			id: v.name,
			orderType: v.orderType, // 排序方式
			quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
			symbol: '',
			type: v.type,
			value: '',
			dataUnit: v.dataUnit || '',
			precision: v.precision
		};
	};

	async getConditionData() {
		const { config = {} } = this.props;
		const { xAxis = [], yLAxis = [], yRAxis = [], series = [] } = config.data;
		if ( xAxis.length && ( yLAxis.length || yRAxis.length ) ) {
			const x = xAxis.map( v => this.itemInfo( v ) );
			const y = yLAxis.map( v => this.itemInfo( v ) );
			const y2 = yRAxis.map( v => this.itemInfo( v ) );
			const category = series.map( v => this.itemInfo( v ) );
			// const conditions = this.props.config.data.filterFields ? this.props.config.data.filterFields.map( v => v.filterConditions ).flat() : [];
			
			// 内部筛选 condition
			const filterFieldCondition = this.props.config.data.filterFields
				? this.props.config.data.filterFields.map( ( v ) => v.filterConditions ).flat()
				: [];

			// 筛选组件的 condition
			let filterCompConditions = this.props.config.data.filterConditions || {};
			let newFilterCompConditions = [];
			Object.keys( filterCompConditions ).forEach( ( key ) => {
				newFilterCompConditions = newFilterCompConditions.concat( filterCompConditions[key] );
			} );

			const request = {
				dataConfig: {
					dataModel: {
						pageId: this.props.pageId,
						tableName: config.data.tableCode,
						x,
						y,
						y2,
						category,
						conditions: filterFieldCondition.concat( this.state.dependencies, newFilterCompConditions )
					},
					needAutoRefresh: true,
					tableType: 'dual'
				},
				type: 'column',
				tenantCode: this.props.tenantCode
			};
			let pageResponse = await getComponentData( request );
			if ( pageResponse.data ) {
				let { rows = [], y2 = [] } = pageResponse.data.data || {};

				// const newRows = transformDataUnitData( rows, y, 'value' );
				// const newY2 = transformDataUnitData( rowsY2, y2, 'value2', 'value' );
				y2 = y2.map( t => {
					return {
						...t,
						value2: t.value
					};
				} );
				if ( pageResponse.data.success && ( rows.length || y2.length ) ) {
					return { rows: rows, y2: y2 };
				}
			}
		}
		return DEFAULT_DATA;
	}

	shouldComponentUpdate( nextProps: Readonly<IProps>, nextState: Readonly<{ dependencies: any }>, nextContext: any ): boolean {
		if ( JSON.stringify( nextProps ) !== JSON.stringify( this.props ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( nextState.dependencies )
		) return true;
		return false;
	}

	getSnapshotBeforeUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }> ): any | null {
		let { config, chartLayout } = this.props;
		let changeObj = Object.create( null );

		const { xAxis = [], yLAxis = [], yRAxis = [], series = [], columnType, filterFields = [], filterConditions = {} } = config.data || {};
		const { xAxis: pxAxis = [], yLAxis: pyLAxis = [], yRAxis: pyRAxis = [], series: pSeries = [], 
			columnType: pColumnType, filterFields: pfilterFields = [], filterConditions: pFilterConditions = {} } = prevProps.config.data || {};

		//	判断数据字段是否变化了
		if ( config.data.tableCode === prevProps.config.data.tableCode && columnType !== pColumnType ) {
			changeObj.needChartTypeChange = true;
		} else if (
			( xAxis.length && ( yLAxis.length || yRAxis.length ) ) &&
			( JSON.stringify( pxAxis ) !== JSON.stringify( xAxis ) ||
				JSON.stringify( pyLAxis ) !== JSON.stringify( yLAxis ) ||
				JSON.stringify( yRAxis ) !== JSON.stringify( pyRAxis ) ||
				JSON.stringify( pSeries ) !== JSON.stringify( series ) ||
				JSON.stringify( pfilterFields ) !== JSON.stringify( filterFields ) ||
				JSON.stringify( this.state.dependencies ) !== JSON.stringify( prevState.dependencies ) ||
			JSON.stringify( pFilterConditions ) !== JSON.stringify( filterConditions ) ) )  {
			changeObj.needDataChange = true;
		}

		//	判断样式是否改变
		if ( JSON.stringify( prevProps.config.data.yLAxisUnit ) !== JSON.stringify( config.data.yLAxisUnit ) ||
			 JSON.stringify( prevProps.config.data.yRAxisUnit ) !== JSON.stringify( config.data.yRAxisUnit ) ||
			 JSON.stringify( prevProps.config.style ) !== JSON.stringify( config.style ) ) {
			changeObj.needStyleChange = true;
		}

		//判断是否因宽高改变重新适应布局
		if ( prevProps.chartLayout.w !== chartLayout.w || prevProps.chartLayout.h !== chartLayout.h ) {
			changeObj.needLayoutChange = true;
		}
		return changeObj;
	}

	initEvent = async () => {
		const resData = await this.getConditionData();
		const { xAxis = [], yLAxis = [], yRAxis = [] } = this.props.config.data;
		const xAlias = xAxis.map( t => t.title ).join( '-' ) || 'name';
		const yLAlias = yLAxis.map( t => t.title ).join( '-' ) || 'value';
		const yRAlias = yRAxis.map( t => t.title ).join( '-' ) || 'value2';
		this.setState( {
			rows: resData.rows,
			y2: resData.y2
		}, () => {
			const barPlot = new DualAxes( this.props.id, this.getConfig() );
			barPlot.render();
			this.setState( {
				xAlias,
				yLAlias,
				yRAlias,
				chartEl: barPlot,
				isRender: true
			}, () => {
				// 修复bug
				this.state.chartEl.update( { theme: { maxColumnWidth: this.props.config.style.columnWidth } } );
			} );

			//	数据联动 组装联动参数
			barPlot.on( 'element:click', ( ev ) => {
				if( !this.props.config.mutual.isChainAvailable ) return;

				const intervalElement = ev.target.get( 'element' );
				const data = intervalElement.getModel().data; // 单条数据
				console.log( data );
				if( Object.prototype.toString.call( data ) === '[object Array]' ) return;
				let dependencies = [];
				const xAxis = this.props.config.data.xAxis || [];
				if( xAxis.length > 0 ) {
					dependencies = dependencies.concat( xAxis.map( ( item, index ) => {
						return {
							formatType: item.formatType,
							id: [ item.name ],
							quota: item.modelType === WD_TYPE ? 'WD' : 'DL',
							symbol: 'EQ',
							value: [ data.name ]		//	从原数据中找到item，一一对应字段
						};
					} ) );
				}

				const series = this.props.config.data.series || [];
				if( series.length > 0 ) {
					dependencies = dependencies.concat( series.map( ( item, index ) => {
						return {
							formatType: item.formatType,
							id: [ item.name ],
							quota: item.modelType === WD_TYPE ? 'WD' : 'DL',
							symbol: 'EQ',
							value: [ data.category ]		//	从原数据中找到item，一一对应字段
						};
					} ) );
				}

				if( dependencies.length === 0 ) return;

				PubSub.publish( CHART_LINK, {
					publisherId: this.props.id,
					listenerIds: this.props.config.mutual.chartsChainIds,
					dimension: dependencies,
					tableCode: this.props.config.data.tableCode
				} );
			} );
		} );
	};

	async componentDidUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{}>, snapshot?: any ) {
		console.log( 'columnLine', snapshot );
		if ( snapshot.needStyleChange ) this.state.chartEl.update( this.getConfig() );

		if ( snapshot.needDataChange ) {
			const { xAxis = [], yLAxis = [], yRAxis = [] } = this.props.config.data;
			const xAlias = xAxis.map( t => t.title ).join( '-' ) || 'name';
			const yLAlias = yLAxis.map( t => t.title ).join( '-' ) || 'value';
			const yRAlias = yRAxis.map( t => t.title ).join( '-' ) || 'value2';
			// console.log( this.state.data );
			const resData = await this.getConditionData();
			this.setState( {
				rows: resData.rows,
				y2: resData.y2,
				xAlias,
				yLAlias,
				yRAlias
			}, () => {
				const data = [ resData.rows, resData.y2 ];
				this.state.chartEl.changeData( data );
			} );
		}

		if ( snapshot.needChartTypeChange ) {
			this.state.chartEl.update( this.getConfig() );
		}
	}

	render() {
		return <div id={this.props.id} style={{ height: '100%' }}></div>;
	}
};
